import {MicroBaseEntryMainConfig, MicroUtils, NavigatorConfig, NavigatorRoutePage, NavigatorRouteType} from 'plain-micro-application';
import React from "react";
import ReactDOM from 'react-dom'
import {nav} from "@/micro/nav/nav";
import {pathJoin} from 'plain-micro-application';
import {getPrivateRoutePage} from "@/micro/route/getPrivateRoutePage";
import {getCommonRoutePage} from "@/micro/route/getCommonRoutePage";
import {getPageRoutePage} from "@/micro/route/getPageRoutePage";
import {LoginService} from "@/login/LoginService";
import {createTokenService} from "@/login/TokenService";
import {designPage, reactive} from "plain-design-composition";

function createRenderer() {
    let setContent: (content: () => any) => void;
    const App = designPage(() => {
        const state = reactive({
            content: null as any
        })
        setContent = content => state.content = content
        return () => <>
            {!!state.content && <state.content/>}
        </>
    })
    ReactDOM.render(<App/>, document.getElementById('app'))
    return {
        render: (content: () => JSX.Element | null) => setContent(content)
    }
}

/**
 * 创建一个初始化执行器
 * @author  韦胜健
 * @date    2021/2/18 11:38
 */
export function createInitialization(
    {
        appName,
        getLoginRender,
        getHomeRender,
        getNavigatorConfig,
    }: {
        appName: string,
        getLoginRender: () => Promise<() => JSX.Element>,
        getHomeRender: () => Promise<() => JSX.Element>,
        getNavigatorConfig: () => Omit<NavigatorConfig, 'routePage' | 'routeType'>,
    }
) {
    return (mainConfig: MicroBaseEntryMainConfig) => {
        // import('../../static/styles/iconfont/iconfont.css')

        const renderer = createRenderer()

        /*LoginService渲染动作对象*/
        const LoginServiceRender = {
            clear: () => renderer.render(() => null),
            home: async () => renderer.render(await getHomeRender()),
            login: async () => renderer.render(await getLoginRender()),
        }

        /**
         * publicPath:  主应用的publicPath，如果当前启动应用为主应用，则publicPath是这个样子的：/micro-crm/，如果是启动应用是子应用，则是
         *              长这个样子的：http://localhost:3021/micro-crm/；
         * @author  韦胜健
         * @date    2021/3/2 15:57
         */
        /*const {publicPath} = mainConfig*/

        const entryPublicPath = MicroUtils.EntryApplicationPublicPathConfigure.get()
        const href = window.location.href

        const handlers = (() => {

            /**
             * 打开home有三种方式，home路由，page路由以及无路由
             * @author  韦胜健
             * @date    2021/3/5 14:33
             */
            const createHomeHandler = (getRoute: () => { routeType: NavigatorRouteType, routePage?: NavigatorRoutePage }) => {
                return async () => {
                    const {routePage, routeType} = getRoute()
                    console.log(`init ${routeType}`)
                    LoginService.init({mainConfig, token: createTokenService(appName), getLoginRender, render: LoginServiceRender,})

                    /**
                     * 有routePage的话，在beforeOpenRoutePage中check，否则在打开home之前check
                     * @author  韦胜健
                     * @date    2021/3/5 14:44
                     */
                    const check = async () => {
                        /*检查登录*/
                        await LoginService.checkLogin()
                        /*登录完了之后初始化用户信息*/
                        await LoginService.user.init()
                    }
                    await nav.init({...getNavigatorConfig(), routePage, routeType,}, !!routePage ? check : undefined)
                    !routePage && await check()
                    LoginService.render.home()
                }
            }

            console.log({
                    entryPublicPath,
                    'NavigatorRouteType.page': NavigatorRouteType.page,
                    'pathJoin(entryPublicPath, NavigatorRouteType.page)': pathJoin(entryPublicPath, NavigatorRouteType.page),
                    'new RegExp(`${pathJoin(entryPublicPath, NavigatorRouteType.page)}/?.*`)': new RegExp(`${pathJoin(entryPublicPath, NavigatorRouteType.page)}/?.*`),
                },
            );

            return [
                /*login*/
                {
                    /**
                     * publicPath+login
                     * 直接打开登录页面，登录完毕之后打开home
                     * @author  韦胜健
                     * @date    2021/2/18 15:54
                     */
                    test: new RegExp(`${pathJoin(entryPublicPath, 'login')}/?.*`),
                    handler: async () => {
                        LoginService.init({
                            mainConfig,
                            token: createTokenService(appName),
                            getLoginRender,
                            render: LoginServiceRender,
                        })
                        await nav.init({
                            ...getNavigatorConfig(),
                            routePage: undefined,
                            routeType: NavigatorRouteType.home,
                        })
                        /*打开登录页面*/
                        await LoginService.login()
                        /*登录完毕之后打开主应用给的首页*/
                        LoginService.render.home()
                        /*移除url中的login路径，跳转到首页路径*/
                        window.history.pushState('', '', entryPublicPath)
                    },
                },
                /*public*/
                {
                    /**
                     * publicPath+public+???
                     * 1. public路由，不需要登录
                     * 2. 系统初始化的时候全屏打开这个页面
                     * 3. 没有token，所以这个页面以及这个页面所跳转的页面都需要考虑token没有的情况
                     * 4. home页面不显示head以及menu
                     * 5. 无法跳转到登录页面登录
                     * @author  韦胜健
                     * @date    2021/2/18 15:55
                     */
                    test: new RegExp(`${pathJoin(entryPublicPath, NavigatorRouteType.public)}/?.*`),
                    handler: async () => {
                        console.log(`init ${NavigatorRouteType.public}`)
                        LoginService.init({
                            mainConfig,
                            token: createTokenService(`${NavigatorRouteType.public.toUpperCase()}_${appName}`),
                            /*public 路由页面不允许登录*/
                            getLoginRender: async () => (() => <></>),
                            render: LoginServiceRender,
                        })
                        /*const routePage = getCommonRoutePage(NavigatorRouteType.public)

                        await nav.init({
                            ...getNavigatorConfig(),
                            routePage: getCommonRoutePage(NavigatorRouteType.public),
                            routeType: NavigatorRouteType.public,
                        }, async () => {
                            if (!!routePage.query.token) {
                                /!*如果url参数中有token，则更新用户信息*!/
                                console.log('public 路由 beforeOpenRoutePage', routePage.query.token)
                                LoginService.token.update(`PRIVATE_ROUTE_USER`, 7199000, routePage.query.token)
                                await LoginService.user.init()
                                LoginService.token.update(LoginService.user.info.username, 7199000, routePage.query.token)
                            }
                        })*/
                        await nav.init({
                            ...getNavigatorConfig(),
                            routePage: getCommonRoutePage(NavigatorRouteType.public),
                            routeType: NavigatorRouteType.public,
                        })
                        LoginService.render.home()
                    },
                },
                /*private*/
                {
                    /**
                     * publicPath+private+???
                     * - 打开home页面，不显示head以及menu；
                     * - url的query字符串中需要带token
                     * - 根据url中的token查询用户信息，更新UserService以及TokenService
                     * - 无法跳转到登录页面登录
                     * @author  韦胜健
                     * @date    2021/2/18 15:55
                     */
                    test: new RegExp(`${pathJoin(entryPublicPath, NavigatorRouteType.private)}/?.*`),
                    handler: async () => {
                        console.log(`init ${NavigatorRouteType.private}`)
                        LoginService.init({
                            mainConfig,
                            token: createTokenService(`${NavigatorRouteType.private}_${appName}`),
                            /*private 路由页面不允许登录*/
                            getLoginRender: async () => (() => <></>),
                            render: LoginServiceRender,
                        })
                        const routePage = getPrivateRoutePage()
                        await nav.init({
                            ...getNavigatorConfig(),
                            routePage,
                            routeType: NavigatorRouteType.private,
                        }, async () => {
                            console.log('private 路由 beforeOpenRoutePage', routePage.query.token)
                            LoginService.token.update(`PRIVATE_ROUTE_USER`, 7199000, routePage.query.token)
                            await LoginService.user.init()
                            LoginService.token.update(LoginService.user.info.username, 7199000, routePage.query.token)
                        })
                        LoginService.render.home()
                    },
                },
                /*home*/
                {
                    /**
                     * publicPath+home+???
                     * - 打开home页面，显示menu以及head
                     * - 需要系统已经登录，没有登录会先打开登录页面登录完毕之后，再打开home页面，打开home页面的时候，直接打开路由的页面，而不是首页
                     * @author  韦胜健
                     * @date    2021/3/2 17:26
                     */
                    test: new RegExp(`${pathJoin(entryPublicPath, NavigatorRouteType.home)}/?.*`),
                    handler: createHomeHandler(() => ({routeType: NavigatorRouteType.home, routePage: getCommonRoutePage(NavigatorRouteType.home)})),
                },
                /*page*/
                {
                    /**
                     * publicPath+page+???
                     * - 打开home页面，不显示menu以及head
                     * - 需要系统已经登录，没有登录会先打开登录页面，登录完毕之后再打开home页面；
                     * - publicPath+page+???后面的是id；通过这个id在本地缓存中插槽页面路径、参数、安全性等信息
                     * page路由，需要系统已经登录，全屏打开页面, 打开的页面信息通过localStorage缓存传递
                     * @author  韦胜健
                     * @date    2021/3/2 17:26
                     */
                    test: new RegExp(`${pathJoin(entryPublicPath, NavigatorRouteType.page)}/?.*`),
                    handler: createHomeHandler(() => ({routeType: NavigatorRouteType.page, routePage: getPageRoutePage()})),
                },
                /*default*/
                {
                    /**
                     * publicPath+/
                     * - 访问home主页面
                     * - 检查登录
                     * @author  韦胜健
                     * @date    2021/2/18 15:56
                     */
                    test: /.*/,
                    handler: createHomeHandler(() => ({routeType: NavigatorRouteType.home})),
                }
            ]
        })();

        for (let i = 0; i < handlers.length; i++) {
            const {test, handler} = handlers[i];
            if (test.test(window.location.pathname)) {
                return handler()
            }
        }
    };
}